package Leo.social.QQ.Api;

import com.alibaba.druid.util.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.social.oauth2.AbstractOAuth2ApiBinding;
import org.springframework.social.oauth2.TokenStrategy;

import java.io.IOException;
public class OAuth2ApiBindingForQQImpl extends AbstractOAuth2ApiBinding implements QQ {

    Logger log = LoggerFactory.getLogger(OAuth2ApiBindingForQQImpl.class);
    /**
     * 调用所有OpenAPI时，除了各接口私有的参数外，所有OpenAPI都需要传入基于OAuth2.0协议的通用参数：
     * 参数	            含义
     * access_token	    可通过使用Authorization_Code获取Access_Token 或来获取。access_token有3个月有效期。
     * oauth_consumer_key	申请QQ登录成功后，分配给应用的appid
     * openid	            用户的ID，与QQ号码一一对应。可通过调用https://graph.qq.com/oauth2.0/me?access_token=YOUR_ACCESS_TOKEN 来获取。
     */
    private String appid;
    private String openid;
    /*
    public static final String GET_USER_INFO_URL = "https://graph.qq.com/user/get_user_info?access_token={token}&oauth_consumer_key={appid}&openid={openid}";
    父类会自动添加access_token={token}的信息，因此这里的路径不需要填写access_token={token
    */
    public static final String GET_USER_INFO_URL = "https://graph.qq.com/user/get_user_info?oauth_consumer_key={appid}&openid={openid}";
    public static final String GET_OPENID_URL = "https://graph.qq.com/oauth2.0/me?access_token={token}";
    //格式转换
    private ObjectMapper objectMapper = new ObjectMapper();

    /**
     * Constructs the API template with OAuth credentials necessary to perform operations on behalf of a user.
     *
     * @param accessToken   the access token
     *
     */
    public OAuth2ApiBindingForQQImpl(String accessToken, String appid) {
        /**
        @param tokenStrategy Specifies how access tokens are sent on API requests. Defaults to sending them in Authorization header.
                *                      指定查询策略，默认是吧token放在请求头上，但是qq要求放在parameters里，所以这里要设定请求策略
         *                      */
        super(accessToken, TokenStrategy.ACCESS_TOKEN_PARAMETER);
        this.appid = appid;
        String result = getRestTemplate().getForObject(GET_OPENID_URL, String.class, accessToken);
        log.debug(result);
        openid = StringUtils.subString(result,"\"openid\":\"","\"}");
    }

    @Override
    public QQUserInfo getUserInfo() {
        String strQqinfo = getRestTemplate().getForObject(GET_USER_INFO_URL, String.class, appid, openid);
        log.debug(strQqinfo);
        try {
            QQUserInfo qqUserInfo = objectMapper.readValue(strQqinfo, QQUserInfo.class); //尚未清楚readValue和convertValue的区别，如果报错，有可能是openid的问题
            qqUserInfo.setOpenid(openid);
            return qqUserInfo;
        }catch(IOException ex){
            ex.printStackTrace();
            throw new RuntimeException("通过openid获取QQ用户信息失败，openid为：" + openid);
        }
    }
}
